-
Notifications
You must be signed in to change notification settings - Fork 28.9k
[SPARK-54415][SQL] CREATE GLOBAL TEMPORARY VIEW / TEMPORARY VIEW supports IF NOT EXISTS clause #53129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| if (!overrideIfExists && viewDefinitions.contains(name)) { | ||
| throw new TempTableAlreadyExistsException(name) | ||
| if (ignoreIfExists && overrideIfExists) { | ||
| throw QueryCompilationErrors.createViewWithBothIfNotExistsAndReplaceError() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it okay to reuse CREATE_OR_REPLACE_WITH_IF_NOT_EXISTS_IS_NOT_ALLOWED, or better suggestion?
| with CTEInChildren | ||
| with CreateTempView { | ||
| with CreateTempView | ||
| with SessionStateHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as I touch this file, I fixed the IDE index issue of the whole file by leveraging SessionStateHelper
| global: Boolean, | ||
| provider: String, | ||
| options: Map[String, String]) extends LeafRunnableCommand { | ||
| options: Map[String, String]) extends LeafRunnableCommand with SessionStateHelper { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, fixes IDE-index issue
| finalSchemaBinding) | ||
| } else { | ||
| // Disallows 'CREATE TEMPORARY VIEW IF NOT EXISTS' to be consistent with | ||
| // 'CREATE TEMPORARY TABLE' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the logic came from SPARK-6339 (Spark 2.0.0), but seems without a clear reason
| // make sure our view doesn't change. | ||
| val viewIdentifier = viewType match { | ||
| case "GLOBAL TEMPORARY VIEW" => | ||
| TableIdentifier("testView", Some(conf.getConf(GLOBAL_TEMP_DATABASE))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
global temp view must be accessed via a qualified name.
| }, | ||
| "CREATE_OR_REPLACE_WITH_IF_NOT_EXISTS_IS_NOT_ALLOWED" : { | ||
| "message" : [ | ||
| "CREATE OR REPLACE <resourceType> with IF NOT EXISTS is not allowed." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can reuse this for other resource types, e.g. TABLE, FUNCTION, PROCEDURE
|
cc @cloud-fan @LuciferYang @dongjoon-hyun BTW, this patch targets 4.2, maybe I should make a small change in the docs to remove the illegal example SQL first, to fix the current docs for all existing active branches? |
|
Curious what is the current behaivor of Whatever we are extending here, we need to consider the backward compability with exsiting behavior (or it becomes a behavior change which we need a way to take care of). |
|
@amaliujia no breaking behavior here, use 4.1.0-preview4 and as you can see, the error message even suggests "add the IF NOT EXISTS clause" |
Then this PR is just extending the feature which makes perfectly sense. |
|
Thank you for pinging me, @pan3793 . +1 for targeting 4.2.0. For docs, maybe for 4.1.0.
|
| overrideIfExists: Boolean): Unit = synchronized { | ||
| if (!overrideIfExists && viewDefinitions.contains(name)) { | ||
| throw new TempTableAlreadyExistsException(name) | ||
| if (ignoreIfExists && overrideIfExists) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So why both ignoreIfExists and overrideIfExists and not just ignoreIfExists?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overrideIfExistsSQL equivalent:OR REPLACEignoreIfExistsSQL equivalent:IF NOT EXISTS
CREATE [ OR REPLACE ] GLOBAL TEMP VIEW [ IF NOT EXISTS ] ...
obviously, OR REPLACE and IF NOT EXISTS can not co-exist, except for this, all other combinations are valid.
Snowflake has the same behavior
https://docs.snowflake.com/en/sql-reference/sql/create-view#general-usage-notes
The
OR REPLACEandIF NOT EXISTSclauses are mutually exclusive. They can’t both be used in the same statement.
…orts IF NOT EXISTS clause
What changes were proposed in this pull request?
Make
CREATE TEMPORARY VIEWandCREATE GLOBAL TEMPORARY VIEWwork withIF NOT EXISTS, like the persistedVIEW.Why are the changes needed?
Currently, Spark SQL supports
CREATE [ OR REPLACE ] [ [ GLOBAL ] TEMPORARY ] VIEW [ IF NOT EXISTS ] view_identifier ...syntax, but the implementation forbids usingCREATE [ GLOBAL ] TEMPORARY VIEWwithIF NOT EXISTS, this is likely an incompleted feature.And this was also provided as an example in the docs, but actually does not work.
https://spark.apache.org/docs/4.0.1/sql-ref-syntax-ddl-create-view.html
In addition, the error condition
TEMP_TABLE_OR_VIEW_ALREADY_EXISTS's message suggests "add the IF NOT EXISTS clause", which does not work either.I also checked Snowflake docs, which indicates support for the above cases too.
https://docs.snowflake.com/en/sql-reference/sql/create-view
Does this PR introduce any user-facing change?
Yes, improves SQL syntax
How was this patch tested?
UTs are added.
Was this patch authored or co-authored using generative AI tooling?
No.